package net.lwf.jaxb.service.maths.worksheet;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.lwf.jaxb.entity.StaticWorkSheet;
import net.lwf.jaxb.service.JaxbService;
import net.lwf.jaxb.stubs.maths.worksheet.File;
import net.lwf.jaxb.stubs.maths.worksheet.Grade;
import net.lwf.jaxb.stubs.maths.worksheet.StaticWorksheets;
import net.lwf.jaxb.stubs.maths.worksheet.Subject;
import net.lwf.jaxb.stubs.maths.worksheet.Topic;
import net.lwf.jaxb.stubs.maths.worksheet.Type;
import net.lwf.number.util.RandomNumberGenerator;
import net.lwf.string.util.StringManipulator;

public class StaticWorkSheetService extends JaxbService {
	
	private String grade;
	
	private static final String CONTEXT_PATH = "net.lwf.jaxb.stubs.maths.worksheet";
	
	private String xmlFileName = "worksheets/static-worksheets";
	
	private String fileExtension = ".xml";
	
	private static Map<String, List<Type>> swsData = new HashMap<String, List<Type>>();
	
	/**
	 * Gets unique worksheet per type.If multiple worksheets are available, random worksheet
	 * is picked per type.
	 * 
	 * @param grade
	 * @param subject
	 * @param topic
	 * @return
	 */
	public List<StaticWorkSheet> getUniqueWorkSheets(String grade, String subject, String topic) {
		List<StaticWorkSheet> uniquesheets = null;
		List<Type> wstypes = getWorkSheetTypes(grade, subject, topic);
		if(wstypes != null) {
			uniquesheets = new ArrayList<StaticWorkSheet>();
			for(Type type: wstypes) {
				List<File> fileinfo = type.getFile();
				int random = 0;
				if(fileinfo.size() > 1) {
					random = RandomNumberGenerator.generate(0, fileinfo.size() - 1);
				}
				File file = fileinfo.get(random);
				//Populate unique worksheet
				StaticWorkSheet worksheet = new StaticWorkSheet();
				worksheet.setId(type.getId().intValue());
				worksheet.setDescription(type.getDescription());
				worksheet.setName(file.getName());
				worksheet.setPath(file.getPath());
				worksheet.setPrintrestriction(file.getPrintrestriction());
				worksheet.setDisplayall(file.getDisplayall());
				worksheet.setStatus(file.getStatus());
				uniquesheets.add(worksheet);
			}			
		}

		return uniquesheets;
	}
	
	/**
	 * Gets unique worksheet.If multiple worksheets are available, random worksheet
	 * is picked for the chosen type.
	 * 
	 * @param grade
	 * @param subject
	 * @param topic
	 * @return
	 */	
	public StaticWorkSheet getUniqueWorkSheet(String grade, String subject, String topic, String typeDesc) {
		StaticWorkSheet worksheet = null;
		List<Type> wstypes = getWorkSheetTypes(grade, subject, topic);
		if(wstypes != null) {
			for(Type type: wstypes) {
				if(type.getDescription().equalsIgnoreCase(typeDesc)) {
					worksheet = new StaticWorkSheet();
					List<File> fileinfo = type.getFile();
					int random = 0;
					if(fileinfo.size() > 1) {
						random = RandomNumberGenerator.generate(0, fileinfo.size() - 1);
					}
					File file = fileinfo.get(random);
					//Populate unique worksheet
					worksheet.setId(type.getId().intValue());
					worksheet.setDescription(type.getDescription());
					worksheet.setName(file.getName());
					worksheet.setPath(file.getPath());
					worksheet.setPrintrestriction(file.getPrintrestriction());
					worksheet.setDisplayall(file.getDisplayall());
					worksheet.setStatus(file.getStatus());
				}
			}			
		}
		return worksheet;
	}
	
	public Type getWorkSheetByType(String grade, String subject, String topic) {
		List<Type> wstypes = getWorkSheetTypes(grade, subject, topic);
		if(wstypes != null) {
			int random = 0;
			if(wstypes.size() > 1) {
				random = RandomNumberGenerator.generate(0, wstypes.size() - 1);
			}
			return wstypes.get(random);			
		}
		return null;
	}
	
	
	/**
	 * Gets all available worksheet types based on the given input. The type info is
	 * stored in a hash map. The info is loaded from the xml as needed.
	 * 
	 * @param grade		Chosen grade
	 * @param subject	Chosen subject
	 * @param topic		Chosen topic
	 * 
	 * @return
	 */
	public List<Type> getWorkSheetTypes(String grade, String subject, String topic) {
		List<Type> type = null;
		String key = grade + subject + topic;
		if(!swsData.containsKey(key)) {
			this.init(grade, subject, topic);
		}
		type = swsData.get(key);
		return type;
	}

	
	/**
	 * Populates the worksheet info from the xml.
	 * 
	 * @param in_grade
	 * @param in_subject
	 * @param in_topic
	 */
	private void init(String in_grade, String in_subject, String in_topic) {
		this.grade = in_grade;
		StaticWorksheets worksheets = (StaticWorksheets) loadedXmlData();
		Grade grade = worksheets.getGrade();
		List<Subject> subjects = grade.getSubject();
		for(Subject subject: subjects) {
			if(subject.getName().equalsIgnoreCase(in_subject)) {
				List<Topic> topics = subject.getTopic();
				for(Topic topic: topics) {
					//The in_topic may contain spaces between the words
					//The same topic from static_worksheets.xml does not contain the spaces
					//Therefore remove the spaces
					if(topic.getName().equalsIgnoreCase(StringManipulator.replace(in_topic, " ", ""))) {
						String key = in_grade + in_subject + in_topic;
						swsData.put(key, topic.getType());
						return;
					}
				}				
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		StaticWorkSheetService service = new StaticWorkSheetService();
		Type type = service.getWorkSheetByType("1", "maths", "money");
		List<File> fileinfo = type.getFile();
		int random = 0;
		if(fileinfo != null) {
			if(fileinfo.size() > 1) {
				random = RandomNumberGenerator.generate(0, fileinfo.size() - 1);
			}			
		}
		File file = fileinfo.get(random);
		System.out.println("---> File Info: Name: " + file.getName() + "; path: " + file.getPath());
		
		System.out.println("\n=================> Unique worksheets <===============================");
		List<StaticWorkSheet> worksheets = service.getUniqueWorkSheets("1", "maths", "addition");
		for(StaticWorkSheet worksheet: worksheets) {
			System.out.println("---> File Info: Name: " + worksheet.getName() + "; path: " + worksheet.getPath() + "; Type: " + worksheet.getDescription());
		}
		
		System.out.println("\n=================> Unique worksheet per the given description <===============================");
		StaticWorkSheet worksheet = service.getUniqueWorkSheet("1", "english", "words", "beginning sounds");
		System.out.println("---> File Info: Name: " + worksheet.getName() + "; path: " + worksheet.getPath() + "; Type: " + worksheet.getDescription());
	}


	@Override
	public String getContextPath() {
		return CONTEXT_PATH;
	}

	@Override
	public String getXmlFileName() {
		return xmlFileName + this.grade + fileExtension;
	}

}
